<template>
  <div class="manage-container">
    <!-- 页面标题和操作按钮 -->
    <div class="page-header">
      <h2>帖子审核管理</h2>
      <div class="header-actions">
        <el-input
          v-model="keyword"
          placeholder="请输入敏感词进行搜索（标题/内容）"
          clearable
          style="width: 260px;"
          @keyup.enter.native="handleSearch"
        />
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
        <el-button 
          type="primary"
          :disabled="selectedPosts.length === 0"
          @click="batchApprove"
          :loading="batchLoading"
        >
          批量通过 ({{ selectedPosts.length }})
        </el-button>
        <el-button 
          type="warning"
          :disabled="selectedPosts.length === 0"
          @click="batchReject"
          :loading="batchLoading"
        >
          批量拒绝 ({{ selectedPosts.length }})
        </el-button>
        <el-button @click="refreshData">刷新</el-button>
      </div>
    </div>

    <!-- 数据表格 -->
    <el-table 
      :data="postsData" 
      v-loading="loading"
      @selection-change="handleSelectionChange"
      stripe
      border
      style="width: 100%"
    >
      <!-- 选择列 -->
      <el-table-column type="selection" width="55" />
      
      <!-- 帖子ID -->
      <el-table-column prop="postId" label="帖子ID" width="80" />
      
      <!-- 发帖用户ID -->
      <el-table-column prop="userId" label="用户ID" width="80" />
      
      <!-- 帖子标题 -->
      <el-table-column prop="title" label="帖子标题" min-width="200" show-overflow-tooltip />
      
      <!-- 帖子内容 -->
      <el-table-column prop="content" label="帖子内容" min-width="300" show-overflow-tooltip />
      
      <!-- 图片预览 -->
      <el-table-column label="图片预览" width="120" align="center">
        <template #default="{ row }">
          <template v-if="row.imageUrls && row.imageUrls.length > 0">
            <el-button 
              type="primary" 
              size="small"
              @click="showImagePreview(row)"
            >
              查看图片 ({{ row.imageUrls.length }})
            </el-button>
          </template>
          <template v-else>
            <span class="no-images">无图片</span>
          </template>
        </template>
      </el-table-column>
      
      <!-- 审核状态 -->
      <el-table-column prop="status" label="审核状态" width="100" align="center">
        <template #default="{ row }">
          <el-tag :type="getStatusType(row.status)">
            {{ getStatusText(row.status) }}
          </el-tag>
        </template>
      </el-table-column>
      
      <!-- 发布时间 -->
      <el-table-column prop="publishTime" label="发布时间" width="160" />
      
      <!-- 操作列 -->
      <el-table-column label="操作" width="150" align="center">
        <template #default="{ row }">
          <el-button type="success" size="small" @click="approvePost(row.postId)">
            通过
          </el-button>
          <el-button type="danger" size="small" @click="rejectPost(row.postId)">
            拒绝
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 自定义确认弹窗 -->
    <el-dialog
      v-model="confirmDialogVisible"
      :title="confirmDialogTitle"
      width="400px"
      center
      :before-close="handleCancel"
    >
      <div class="confirm-content">
        <el-icon class="confirm-icon" :class="`el-icon-${confirmDialogType}`">
          <Warning v-if="confirmDialogType === 'warning'" />
        </el-icon>
        <span class="confirm-message">{{ confirmDialogMessage }}</span>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleConfirm">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图片预览对话框 -->
    <el-dialog
      v-model="imageDialogVisible"
      title="图片预览"
      width="80%"
      :before-close="handleImageDialogClose"
    >
      <div class="image-preview-container">
        <div v-if="currentPostImages.length === 0" class="no-images">
          该帖子暂无图片
        </div>
        <div v-else class="images-grid">
          <div 
            v-for="(image, index) in currentPostImages" 
            :key="index"
            class="image-item"
          >
            <el-image
              :src="image.imageUrl"
              :preview-src-list="currentPostImages.map(img => img.imageUrl)"
              :initial-index="index"
              fit="cover"
              class="preview-image"
            />
            <div class="image-info">
              <span>顺序: {{ image.sortOrder }}</span>
              <span>上传时间: {{ formatTime(image.uploadTime) }}</span>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import axios from '@/utils/axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Warning } from '@element-plus/icons-vue'

/**
 * 页面级全局加载状态。
 * - 置为 true 时表格与列表区域进入加载态，避免重复触发请求。
 */
const loading = ref(false)

/**
 * 批量操作（如“批量通过”）的加载状态，仅作用于按钮本身，避免影响列表交互。
 */
const batchLoading = ref(false)

/**
 * 当前页的帖子数据集合。
 * 元素示例：
 * {
 *   postId: number,
 *   userId: number,
 *   title: string,
 *   content: string,
 *   status: 0|1|2,
 *   publishTime: string,
 *   imageUrls?: string[],   // 后续补齐
 *   imageCount?: number     // 后续补齐
 * }
 */
const postsData = ref([])

/**
 * 多选框当前被选中的帖子集合。
 * 供“批量通过”等操作使用。
 */
const selectedPosts = ref([])

/**
 * 当前页码（从 1 开始），与分页组件双向绑定。
 */
const currentPage = ref(1)

/**
 * 每页显示条目数，与分页组件双向绑定。
 */
const pageSize = ref(20)

/**
 * 数据总条数，用于计算分页页码。
 * - 优先使用服务端返回的 total
 * - 若无则按需要在前端估算
 */
const total = ref(0)

// 搜索关键词（敏感词）
const keyword = ref('')

/**
 * 图片预览对话框是否显示。
 */
const imageDialogVisible = ref(false)

/**
 * 当前选中的帖子的图片数组。
 * - 结构一般为后端返回的 { imageUrl, sortOrder, uploadTime }
 */
const currentPostImages = ref([])

/** 以下为自定义确认弹窗相关状态（替代 MessageBox 以便统一居中与样式） */
const confirmDialogVisible = ref(false)

/** 弹窗标题 */
const confirmDialogTitle = ref('')

/** 弹窗正文 */
const confirmDialogMessage = ref('')

/** 弹窗类型（warning/success/...）用于控制图标/色彩 */
const confirmDialogType = ref('warning')

/** 点击“确定”时执行的回调（可为异步函数） */
const confirmCallback = ref(null)

/**
 * 接口资源前缀（实际请求路径 = axios.baseURL('/api') + API_BASE）。
 */
const API_BASE = '/posts'

/**
 * 显示自定义确认弹窗。
 * @param title 标题
 * @param message 正文
 * @param callback 用户点击“确定”后的回调（可异步）
 */
const showConfirmDialog = (title, message, callback) => {
  confirmDialogTitle.value = title
  confirmDialogMessage.value = message
  confirmDialogType.value = 'warning' // 默认类型
  confirmCallback.value = callback  // 确认回调
  confirmDialogVisible.value = true  // 显示弹窗
}

/** 执行确认回调并关闭自定义确认弹窗。 */
const handleConfirm = () => {
  if (confirmCallback.value) {
    confirmCallback.value()
  }
  confirmDialogVisible.value = false
}

/** 关闭自定义确认弹窗（取消）。 */
const handleCancel = () => {
  confirmDialogVisible.value = false
}
/**
 * 拉取“未审核”帖子分页数据。
 * - 传参：page/currentPage，limit/pageSize
 * - 兼容两类返回：纯数组 / 分页对象（{records/rows,total,count,current/page,size/limit}）
 * - 拉取完成后并发补齐每条记录的图片信息（用于按钮数量与预览）
 */
const fetchPendingPosts = async () => {
  try {
    loading.value = true
    const kw = (keyword.value || '').trim()
    const endpoint = kw ? 'searchSensitive' : 'pendingReview'
    const params = {
      page: currentPage.value,
      limit: pageSize.value
    }
    if (kw) {
      // 仅在有关键词时传递 keyword 参数
      params.keyword = kw
    }
    const response = await axios.get(`${API_BASE}/${endpoint}`, { params })
    
    if (response.code === 200) {
      console.log('后端返回的数据结构:', response)
      const data = response.data

      // 兼容两种返回：数组 或 分页对象
      if (Array.isArray(data)) {
        // 仅返回当前页数组
        postsData.value = data
      } else {
        // 返回分页对象
        const pageData = data || {}
        // records/rows 二选一兼容
        postsData.value = pageData.records || pageData.rows || []
        // total/count 兼容
        total.value = pageData.total ?? pageData.count ?? postsData.value.length
        // 同步当前页、每页大小（若提供）
        if (pageData.current) currentPage.value = pageData.current
        if (pageData.page) currentPage.value = pageData.page
        if (pageData.size) pageSize.value = pageData.size
        if (pageData.limit) pageSize.value = pageData.limit
        if (pageData.total) pageData.total = pageData.total
      }

      // 保障：若后端未生效过滤，这里再次按关键词进行前端过滤
      if (kw) {
        const lower = kw.toLowerCase()
        postsData.value = postsData.value.filter(p => {
          const title = (p.title || '').toString().toLowerCase()
          const content = (p.content || '').toString().toLowerCase()
          return title.includes(lower) || content.includes(lower)
        })
      }

      // 重置多选以避免对旧数据进行操作
      selectedPosts.value = []

      // 在分页数据就绪后，补充查询每条帖子的图片列表（用于按钮数量与预览）
      try {
        const imageRequests = postsData.value.map(item =>
          axios.get('/postImages/getByPostId', { params: { postId: item.postId } })
            .then(res => {
              if (res && res.code === 200) {
                // 标准化为数组，便于按钮计数与预览
                const list = Array.isArray(res.data) ? res.data : []
                // 同时提供 imageUrls（数组）和 imageCount（数字）
                item.imageUrls = list.map(img => img.imageUrl || img)
                item.imageCount = item.imageUrls.length
              } else {
                item.imageUrls = []
                item.imageCount = 0
              }
            })
            .catch(() => {
              item.imageUrls = []
              item.imageCount = 0
            })
        )
        await Promise.all(imageRequests)
      } catch (_) {
        // 忽略图片补充查询的错误，主表数据仍可展示
      }

      console.log('当前页数据长度:', postsData.value.length)
      console.log('每页限制:', pageSize.value)
      console.log('总记录数:', total.value)
    } else {
      ElMessage.error(response.msg || '获取数据失败')
    }
  } catch (error) {
    console.error('获取未审核帖子失败:', error)
    ElMessage.error('获取数据失败')
  } finally {
    loading.value = false
  }
}

/**
 * 执行搜索：重置到第 1 页，并刷新数据。
 */
const handleSearch = () => {
  currentPage.value = 1
  fetchPendingPosts()
}

/**
 * 重置搜索条件并刷新数据。
 */
const resetSearch = () => {
  keyword.value = ''
  currentPage.value = 1
  fetchPendingPosts()
}

/**
 * 批量审核通过所选帖子。
 * - 校验：至少选择一条
 * - 确认弹窗后：以 postIds=1&postIds=2 的形式提交给后端（@RequestParam List<Integer>）
 */
const batchApprove = async () => {
  if (selectedPosts.value.length === 0) {
    ElMessage.warning('请选择要审核的帖子')
    return
  }

  showConfirmDialog(
    '批量审核确认',
    `确定要通过选中的 ${selectedPosts.value.length} 个帖子吗？`,
    async () => {
      try {
        batchLoading.value = true
        const postIds = selectedPosts.value.map(post => post.postId)
        const response = await axios.post(`${API_BASE}/batchApprove?${postIds.map(id => `postIds=${id}`).join('&')}`)

        if (response.code === 200) {
          ElMessage.success('批量审核通过成功')
          await fetchPendingPosts()
          selectedPosts.value = []
        } else {
          ElMessage.error(response.msg || '批量审核失败')
        }
      } catch (error) {
        console.error('批量审核失败:', error)
        ElMessage.error('批量审核失败')
      } finally {
        batchLoading.value = false
      }
    }
  )
}

/**
 * 批量拒绝所选帖子。
 * - 循环调用 /posts/update，提交 { postId, status: 2 }
 */
const batchReject = async () => {
  if (selectedPosts.value.length === 0) {
    ElMessage.warning('请选择要拒绝的帖子')
    return
  }

  showConfirmDialog(
    '批量拒绝确认',
    `确定要拒绝选中的 ${selectedPosts.value.length} 个帖子吗？`,
    async () => {
      try {
        batchLoading.value = true
        const postIds = selectedPosts.value.map(post => post.postId)
        // 调用后端批量拒绝接口：/posts/batchReject?postIds=1&postIds=2
        const response = await axios.post(`${API_BASE}/batchReject?${postIds.map(id => `postIds=${id}`).join('&')}`)

        if (response.code === 200) {
          ElMessage.success('批量拒绝成功')
        } else {
          ElMessage.error(response.msg || '批量拒绝失败')
        }
        await fetchPendingPosts()
        selectedPosts.value = []
      } catch (error) {
        console.error('批量拒绝失败:', error)
        ElMessage.error('批量拒绝失败')
      } finally {
        batchLoading.value = false
      }
    }
  )
}

/**
 * 审核通过单条帖子。
 * @param postId 帖子主键 ID
 */
const approvePost = async (postId) => {
  showConfirmDialog(
    '审核确认',
    '确定要通过这个帖子吗？',
    async () => {
      try {
         const response = await axios.post(`${API_BASE}/update`, {
           postId: postId,
           status: 1
         })

        if (response.code === 200) {
          ElMessage.success('审核通过成功')
          await fetchPendingPosts()
        } else {
          ElMessage.error(response.msg || '审核失败')
        }
      } catch (error) {
        console.error('审核失败:', error)
        ElMessage.error('审核失败')
      }
    }
  )
}

/**
 * 审核拒绝单条帖子。
 * @param postId 帖子主键 ID
 */
const rejectPost = async (postId) => {
  showConfirmDialog(
    '审核确认',
    '确定要拒绝这个帖子吗？',
    async () => {
      try {
         const response = await axios.post(`${API_BASE}/update`, {
           postId: postId,
           status: 2
         })

        if (response.code === 200) {
          ElMessage.success('审核拒绝成功')
          await fetchPendingPosts()
        } else {
          ElMessage.error(response.msg || '审核失败')
        }
      } catch (error) {
        console.error('审核失败:', error)
        ElMessage.error('审核失败')
      }
    }
  )
}

/**
 * 拉取并显示单条帖子的图片预览。
 * @param row 表格行对象，需包含 postId
 */
const showImagePreview = async (row) => {
  try {
    const response = await axios.get('/postImages/getByPostId', {
      params: { postId: row.postId }
    })
    
    if (response.code === 200) {
      currentPostImages.value = response.data || []
      imageDialogVisible.value = true
    } else {
      ElMessage.error('获取图片失败')
    }
  } catch (error) {
    console.error('获取图片失败:', error)
    ElMessage.error('获取图片失败')
  }
}

/** 重新拉取列表（保持当前分页参数）。 */
const refreshData = () => {
  fetchPendingPosts()
}

/**
 * 表格勾选变化回调。
 * @param selection 勾选的行集合
 */
const handleSelectionChange = (selection) => {
  selectedPosts.value = selection
}

/**
 * 分页尺寸变化回调。
 * @param val 新的每页条数
 */
const handleSizeChange = (val) => {
  pageSize.value = val
  currentPage.value = 1
  fetchPendingPosts()
}

/**
 * 页码变化回调。
 * @param val 新的页码
 */
const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchPendingPosts()
}

/** 关闭图片预览对话框并清空图片数据缓存。 */
const handleImageDialogClose = () => {
  imageDialogVisible.value = false
  currentPostImages.value = []
}

/**
 * 将业务状态转换为 Element Plus Tag 类型。
 * @param status 0=未审核；1=已通过；2=已拒绝
 */
const getStatusType = (status) => {
  const statusMap = {
    0: 'warning',  // 未审核
    1: 'success',  // 审核通过
    2: 'danger'    // 审核不通过
  }
  return statusMap[status] || 'info'
}

/**
 * 将业务状态转换为可读文本。
 * @param status 0/1/2 同上
 */
const getStatusText = (status) => {
  const statusMap = {
    0: '未审核',
    1: '已通过',
    2: '已拒绝'
  }
  return statusMap[status] || '未知'
}

/**
 * 本地化格式化时间展示。
 * @param timeStr 时间字符串/时间戳
 */
const formatTime = (timeStr) => {
  if (!timeStr) return '-'
  const date = new Date(timeStr)
  return date.toLocaleString('zh-CN')
}

/** 组件挂载后立即拉取首屏数据。 */
onMounted(() => {
  fetchPendingPosts()
})
</script>

<style scoped>
.manage-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #e6e6e6;
}

.page-header h2 {
  margin: 0;
  color: #303133;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.image-preview-container {
  max-height: 600px;
  overflow-y: auto;
}

.no-images {
  text-align: center;
  color: #909399;
  padding: 20px;
}

.images-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 15px;
}

.image-item {
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  overflow: hidden;
}

.preview-image {
  width: 100%;
  height: 150px;
}

.image-info {
  padding: 8px;
  background-color: #f5f7fa;
  font-size: 12px;
  color: #606266;
  display: flex;
  justify-content: space-between;
}

:deep(.el-table .cell) {
  word-break: break-word;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

/* 强制居中所有MessageBox弹窗 */
:deep(.el-message-box) {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  z-index: 9999 !important;
}

:deep(.el-message-box__wrapper) {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  z-index: 9999 !important;
}

/* 针对自定义类的额外样式 */
:deep(.center-dialog) {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  z-index: 9999 !important;
}

/* 全局样式，确保所有MessageBox都居中 */
.el-message-box {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  z-index: 9999 !important;
}

.el-message-box__wrapper {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  z-index: 9999 !important;
}

/* 自定义确认弹窗样式 */
.confirm-content {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0;
}

.confirm-icon {
  font-size: 24px;
  color: #e6a23c;
}

.confirm-message {
  font-size: 16px;
  color: #606266;
}

.dialog-footer {
  text-align: right;
}
</style>